/*
 * @Copyright: (C) 2019 Zhang Rida. All rights reserved.
 *
 * @Author: Zhang Rida
 * @Email: 215154317@qq.com
 * @FilePath: /WEILA_SDK_MODULE/src/wlsdk/src/repo.h
 * @Date: 2021-02-27 17:08:35
 * @Description:
 *
 * @LastEditors: Zhang Rida
 * @LastEditTime: 2024-09-11 14:12:30
 * 配置描述
 *
 * {
    "版本":"设备",
    "version":1,
    "只读配置":"",
    "readonly":{
        "群附着数量":"",
        "attach_limit":1,
        "群数量限制":"",
        "group_limit":1,
        "sos 手机号数量限制":"",
        "sos_phone_limit":3,
        "sos 微喇单呼数量限制":"",
        "sos_single_limit":3,
        "sos 微喇群呼数量限制":"",
        "sos_group_limit":1,
        "最大音量":"",
        "volume_max":8
    },
    "sos_phones":[
        {
            "name":"张三",
            "phone":"18675500568"
        },
        {
            "name":"李四",
            "phone":"18675500568"
        }
    ],
    "sos_singles":[
        {
            "id":1234,
            "number":"1231234"
        }
    ],
    "sos_groups":[
        {
            "id":1234,
            "number":"1231234"
        }
    ],
    "定位模式":"",
    "location_mode":{
        "类型":"0 省电(30分钟一次) 1 普通(10分钟一次) 2 性能(5分钟一次)",
        "type":0,
        "上报间隔":"单位秒",
        "interval":1800
    },
    "围栏":"",
    "geofences":[
        {
            "中心点":"",
            "center":{
                "中心点经度":"",
                "lon":112.3123,
                "中心点纬度":"",
                "lat":22.232
            },
            "围栏半径":"",
            "radius":200
        }
    ],
    "音量":"不能为0",
    "volume":1
}*/
#ifndef _REPO_H
#define _REPO_H

#include "wl_osal.h"
#include "wlsdk_define.h"

#include "WLcJSON.h"

#ifdef __cplusplus
extern "C" {
#endif

#define REPO_GROUP_MAX 20
#define REPO_FRIEND_MAX 100
#define REPO_DNS_MAX 10

#define REPO_GROUP_SESSION_ATTACH_MAX 1        // 群会话附着最大数量
#define REPO_LOCATION_INTERVAL 1800            // 默认30分钟上报一次位置
#define REPO_LOCATION_INTERVAL_MIN 5           // 位置上报最小时间5秒
#define REPO_LOCATION_INTERVAL_MAX 7200        // 位置上报最大时间2小时
#define REPO_VOLUME 7                          // 默认音量
#define REPO_FIXED_SESSION_MAX REPO_GROUP_MAX  // 固定会话与群数量一致
#define REPO_TMP_SESSION_MAX 5                 // 最多5个临时会话
#define REPO_SESSION_MAX (REPO_FIXED_SESSION_MAX + REPO_TMP_SESSION_MAX)

// #define REPO_GROUP_SESSION_PRORITY 0      //群会话优先级(越大越优先)
// #define REPO_SINGLE_SESSION_PRORITY 1     //单人会话优先级(越大越优先)
// #define REPO_GROUP_TMP_SESSION_PRORITY 1  //临时群会话优先级(越大越优先)
// #define REPO_SERVICE_SESSION_PRORITY 2    //服务会话优先级(越大越优先)

#define REPO_INVALID_SESSION_PRORITY 0          // 会话优先级(越大越优先)
#define REPO_DEFAULT_SESSION_PRORITY 1          // 会话优先级(越大越优先)
#define REPO_TMP_SESSION_PRORITY_COUNT 4        // 会话优先级(越大越优先)
#define REPO_QUEUE_SESSION_PRORITY 5            // 会话优先级(越大越优先)
#define REPO_ACTIVE_SESSION_PRORITY 6           // 会话优先级(越大越优先)
#define REPO_DISPATCH_QUEUE_SESSION_PRORITY 7   // 会话优先级(越大越优先)
#define REPO_DISPATCH_ACTIVE_SESSION_PRORITY 8  // 会话优先级(越大越优先)

#define REPO_SESSION_ACTIVE_LIFETIME 10  // 活跃会话生命期(0永远)单位秒
#define REPO_SESSION_TMP_DURATION 7200   // 临时会话时长单位秒

#define REPO_PLAYBACK_SUPPORT

#define REPO_TTS_MAX (REPO_SESSION_MAX + 10)

typedef enum {
    REPO_SESSION_TYPE_SINGLE  = WLSDK_SESSION_TYPE_SINGLE,  // 个人会话未临时通话,10秒无通话会自动释放
    REPO_SESSION_TYPE_GROUP   = WLSDK_SESSION_TYPE_GROUP,
    REPO_SESSION_TYPE_SERVICE = WLSDK_SESSION_TYPE_SERVICE,
    REPO_SESSION_TYPE_CORP_SINGLE    = 0x11,  // 企业个人会话
    REPO_SESSION_TYPE_CORP_GROUP     = 0x12,  // 企业群会话
    REPO_SESSION_TYPE_CORP_GROUP_TMP = 0x13   // 企业临时群会话
} repo_session_type;

typedef enum {
    REPO_GROUP_NORMAL      = 1,     // 正式群
    REPO_GROUP_TMP         = 2,     // 临时群
    REPO_GROUP_CORP_NORMAL = 0x11,  // 企业正式群
    REPO_GROUP_CORP_TMP    = 0x12   // 企业临时群
} repo_group_type;

typedef enum {
    REPO_FRIEND_SINGLE      = 0,  // 个人好友
    REPO_FRIEND_CORP_DEPT   = 1,  // 企业部门成员
    REPO_FRIEND_CORP_MEMBER = 2   // 企业成员
} repo_friend_type;

typedef enum { REPO_DEVICE_SLAVE = 0, REPO_DEVICE_SUB = 1 } repo_device_type;
typedef enum {
    REPO_CLIENT_SMART           = 0x21,
    REPO_CLIENT_EMBEDDED        = 0x24,
    REPO_CLIENT_EMBEDDED_ATTACH = 0x25
} repo_client_type;

#define REPO_DEVICE_TYPE REPO_DEVICE_SUB

// 子设备类型为嵌入式ATTACH客户端类型
#if (REPO_DEVICE_TYPE == REPO_DEVICE_SUB)
#    define REPO_CLIENT_TYPE REPO_CLIENT_EMBEDDED
#else
#    define REPO_CLIENT_TYPE REPO_CLIENT_EMBEDDED
#endif

typedef struct __repo_appkey {
    wl_char appid[MAX_APPID_LEN];
    wl_char appkey[MAX_APPKEY_LEN];
} repo_appkey;

typedef struct __repo_sign {
    wl_char   appid[MAX_APPID_LEN];
    wl_char   sign[MAX_APPKEY_LEN];
    wl_uint64 expire_time;
} repo_sign;

typedef struct __repo_hardware {
    wl_char   id[MAX_ID_LEN];
    wl_char   product[MAX_NAME_LEN];  // 产品名称
    wl_char   imei[MAX_IMEI_LEN];
    wl_char   imsi[MAX_IMSI_LEN];
    wl_char   version[MAX_VERSION_LEN];
    wl_uint32 version_number;
    wl_char   firmware[MAX_NAME_LEN];
    wl_uint32 source_type;
} repo_hardware;

typedef struct __repo_account {
    wl_char account[MAX_ACCOUNT_LEN];
    wl_char country_code[MAX_COUNTRYCODE_LEN];
    wl_char password[MAX_PASSWORD_LEN];
    wl_bool ismd5pwd;
} repo_account;

typedef struct __repo_url {
    wl_char url[MAX_URL_LEN];
} repo_url;

typedef struct __repo_server {
    wl_char   host[MAX_HOST_LEN];
    wl_uint16 port;
} repo_server;

typedef struct __repo_user {
    wlsdk_user user;
    wl_uint16  type;  // 0 普通用户 1 设备用户 16 企业用户 17 企业设备用户
} repo_user;

typedef struct __repo_location_mode {
    wl_int32 type;      // 定位类型 "0 省电(30分钟一次) 1 普通(10分钟一次) 2 性能(5分钟一次)"
    wl_int32 interval;  // 定位间隔时间(间隔时间不能超过1小时)
} repo_location_mode;

typedef struct __repo_geofence {
    wl_uint64 id;
    wl_double latitude;
    wl_double longitude;
    wl_double radius;
    wl_int32  status;             // 0关闭 1开启
    wl_uint16 transition_status;  // 1 在围栏内 2 在围栏外 初始状态
    wl_uint32 latest_report;      // 最近围栏告警时间
} repo_geofence;

typedef struct __repo_button {
    wl_int32  idx;  // 按键索引 0,1,2,3
    wl_uint64 sessionid;
    wl_uint16 sessiontype;
    wl_char   name[MAX_NAME_LEN];
    wl_char   number[MAX_ACCOUNT_LEN];
    wl_int32  type;  // 0 PTT 1 电话
} repo_button;

typedef struct __repo_contact {
    wl_char name[MAX_NAME_LEN];
    wl_char phone[MAX_ACCOUNT_LEN];
    wl_char country_code[MAX_COUNTRYCODE_LEN];
} repo_contact;

typedef struct __repo_session {
    wlsdk_session session;
    wl_time       sync_timestamp;  // 临时群同步时间 大于0标识已同步
    wl_time       latest_burst;    // 最后通话时间
    wl_time       latest_active;   // 最后活跃时间
} repo_session;

typedef struct __repo_pttdata {
    wl_uint32 marker;       // 0x00 话音首包 0x01 话音中间包 0x02 话音分段包 0x03 语音整段 0xff 丢弃
    wl_uint32 seq;          // 话音序号 每段话音自增
    wl_uint32 packageseq;   // 段内分包 0为首包 用于未来支持UDP协议组包
    wl_uint32 source;       // 音源类型 AudioSourceType或由终端定义
    wl_uint32 frame_count;  // 帧数
    wl_uint32 payload_type;                // 编码类型
    wl_char   payload[ZERO_CONTENT_SIZE];  // 编码数据
} repo_pttdata;

typedef struct __repo_audiodata {
    wl_uint32 payload_type;  // 0 url 1 audiodata
    wl_char   payload[ZERO_CONTENT_SIZE];
} repo_audiodata;

typedef struct __repo_playback {
    wlsdk_session session;
    wl_uint32     senderid;
    wl_char       sendername[MAX_NAME_LEN];
    wl_uint32     msgid;
    wl_uint64     created;
    wl_uint32     duration;
    wl_uint32     framecount;
    wl_uint32     audiolen;
    wl_char       audio[ZERO_CONTENT_SIZE];
} repo_playback;

typedef struct __repo_corp {
    wl_uint64 number;
    wl_char   name[MAX_NAME_LEN];
    wl_uint32 group_version;
    wl_uint32 address_version;
    wl_uint32 tts;
    wl_uint32 loc_share;
    wl_uint32 track;
    wl_uint32 state;
} repo_corp;

typedef struct __repo_friend {
    wlsdk_friend friend;
    wl_uint16 type;
} repo_friend;

typedef struct __repo_group {
    wlsdk_group group;
} repo_group;

typedef struct __repo_extension_bind {
    wl_uint32 binderid;
    wl_char   binder_nick[MAX_NAME_LEN];
    wl_char   verify_code[MAX_VERIFYCODE_LEN];
} repo_extension_bind;

typedef struct __repo_dns {
    wl_char host[MAX_HOST_LEN];
    wl_char ip[MAX_IP_LEN];
} repo_dns;

typedef struct __repo_tts_audio {
    wl_uint32 size;
    wl_char   data[ZERO_CONTENT_SIZE];
} repo_tts_audio;

wl_int32  repo_init(void);
wl_int32  repo_end(void);
wl_int32  repo_set_appkey(repo_appkey* appkey);
wl_int32  repo_get_appkey(OUT repo_appkey* appkey);
wl_int32  repo_build_http_sign(WLcJSON* obj);
wl_int32  repo_get_sign(repo_sign* sign);
wl_int32  repo_set_hardware(repo_hardware* hardware);
wl_int32  repo_get_hardware(OUT repo_hardware* hardware);
void      repo_set_system_info(wl_uint32 daemon_duration,
                               wl_uint32 memory_retoot,
                               wl_uint32 sdk_memory,
                               wl_uint32 memory);      // 系统信息
wl_uint32 repo_get_system_last_daemon_duration(void);  // 上次运行时长
wl_uint32 repo_get_system_last_version_num(void);      // 上次版本号
wl_uint32 repo_get_system_last_sdk_memory(void);       // 上次SDK剩余内存
wl_uint32 repo_get_system_last_memory(void);           // 上次剩余内存
wl_uint32 repo_get_system_last_memory_reboot(void);    // 上次内存重启
wl_int32  repo_set_account(repo_account* account);
wl_int32  repo_get_account(OUT repo_account* account);
wl_int32  repo_set_corp(repo_corp* corp);
wl_int32  repo_get_corp(OUT repo_corp* corp);
wl_bool   repo_is_corp_user(void);
wl_uint32 repo_get_corp_address_version(void);
wl_int32  repo_set_corp_address_list(wl_uint32 version, repo_friend* friends, wl_uint32 count);
wl_uint32 repo_get_corp_group_version(void);
wl_int32  repo_set_corp_groups(wl_uint32 version, repo_group* groups, wl_uint32 count);
wl_uint32 repo_get_session_message_session_type(
    wl_uint64 sessionid,
    wl_uint32 session_type);  // 将本地会话类型转换成消息会话类型(企业设备本地会话类型与消息会话类型不一致)

wl_int32  repo_set_managerid(wl_uint32 userid);
wl_uint32 repo_get_managerid(void);
wl_int32  repo_set_login_url(repo_url* url);
wl_int32  repo_get_login_url(OUT repo_url* url);
wl_int32  repo_set_web_server(repo_server* server);
wl_int32  repo_get_web_server(OUT repo_server* server);
wl_int32  repo_set_voip_auto_accept(wl_bool auto_accept);
wl_int32  repo_set_token(wl_char* token);
wl_int32  repo_get_token(OUT wl_char* token);
wl_time   repo_get_server_timestamp(void);
void      repo_set_server_timestamp(wl_time timestamp);
void      repo_adjust_server_timestamp(wl_int32 seconds);
wl_int32  repo_set_user_config(wl_char* config);
wl_char*  repo_get_user_config(void);
wl_int32  repo_set_extension_config(wl_char* config);
wl_uint32 repo_get_extension_config_version(void);
wl_uint32 repo_get_extension_config_location_interval(void);
wl_uint32 repo_get_extension_config_volume(void);
wl_list*  repo_get_extension_config_geofence_list(void);
void      repo_set_extension_config_geofence_transition_status(wl_uint64 id, wl_uint32 transition_status);
wl_uint32 repo_get_extension_config_attach_limit(void);
wl_uint32 repo_get_extension_config_device_type(void);
wl_uint32 repo_get_extension_config_client_type(void);
wl_int32  repo_get_extension_config_imsi(OUT wl_char* imsi);
wl_int32  repo_get_extension_config_button(wl_int32 idx, repo_button* button);
wl_bool   repo_get_extension_config_location_share(void);

wl_uint32 repo_get_userid(void);
wl_int32  repo_set_selfinfo(repo_user* userinfo);
wl_int32  repo_get_selfinfo(OUT repo_user* userinfo);
void      repo_clear_account(void);
wl_int32  repo_set_login_state(wl_int32 state);
wl_int32  repo_get_login_state(void);
wl_int32  repo_set_extension_state(wl_int32 state);
wl_int32  repo_get_extension_state(void);
wl_int32  repo_set_extension_bind(repo_extension_bind* extension_bind);
wl_int32  repo_get_extension_bind(repo_extension_bind* extension_bind);
wl_bool   repo_is_normal_group(wl_uint64 groupid);
wl_list*  repo_get_group_list(void);  // 调用者不可修改list
void      repo_clear_group_list(void);
wl_int32  repo_add_groups(repo_group* groups, wl_uint32 count);
wl_int32  repo_del_groups(wl_uint64* groupIds, wl_uint32 count);
wl_int32  repo_get_group(wl_uint64 groupId, repo_group* group);
wl_int32  repo_set_friend_updated(wl_uint64 updated);
wl_uint64 repo_get_friend_updated(void);
wl_int32  repo_set_friends(wl_uint64 updated, repo_friend* friends, wl_uint32 count);
void      repo_refresh_friend_sessions(void);
wl_list*  repo_get_friend_list(void);  // 调用者不可修改list
void      repo_clear_friend_list(void);
wl_int32  repo_delete_friend(wl_uint32 userid);
wl_int32  repo_get_friend(wl_uint32 userid, repo_friend* friend);

wl_list*  repo_get_session_list(void);
void      repo_clear_session_list(void);
wl_bool   repo_remove_invalid_session(void);
void      repo_refresh_group_sessions(void);
void      repo_add_single_manager_session(void);
wl_int32  repo_update_friend_session(repo_friend* friend);
wl_int32  repo_update_group_session(repo_group* group);
wl_int32  repo_add_session(repo_session* session, wl_int32 pos);
wl_int32  repo_del_session(wl_uint64 sessionid, wl_uint32 sessiontype);
wl_int32  repo_close_session(wl_uint64 sessionid, wl_uint32 sessiontype);
wl_int32  repo_get_session(wl_uint64 sessionid, wl_uint32 sessiontype, repo_session* session);
wl_int32  repo_get_session_by_pos(wl_uint32 pos, repo_session* session);
wl_int32  repo_update_session_name(wl_uint64 sessionid, wl_uint32 sessiontype, wl_char* name);
wl_int32  repo_update_session_sync_timestamp(wl_uint64 sessionid, wl_uint32 sessiontype, wl_time timestamp);
wl_int32  repo_update_session_online(wl_uint64 sessionid, wl_uint32 sessiontype, wl_uint32 online_count);
wl_int32  repo_refresh_session_burst(wl_uint64 sessionid, wl_uint32 sessiontype);
wl_int32  repo_set_active_session(repo_session* session);
wl_int32  repo_get_active_session(repo_session* session);
void      repo_set_tmp_session_keeptime(wl_uint32 duration);
wl_int32  repo_refresh_default_session(void);
wl_int32  repo_set_default_session(wl_uint64 sessionid, wl_uint16 sessiontype);
wl_int32  repo_get_default_session(repo_session* session);
wl_int32  repo_get_session_prority(wl_uint64 sessionid, wl_uint32 sessiontype);
wl_bool   repo_is_session_default(wl_uint64 sessionid, wl_uint16 sessiontype);
wl_bool   repo_is_session_active(wl_uint64 sessionid, wl_uint16 sessiontype);
wl_bool   repo_is_session_burst_release(wl_uint64 sessionid, wl_uint16 sessiontype);
wl_uint32 repo_get_session_burst_time_remaining(wl_uint64 sessionid, wl_uint16 sessiontype);
wl_bool repo_is_normal_group_session(wl_uint64 sessionid, wl_uint32 sessiontype);
wl_int32 repo_add_friend_session(repo_friend* friend);

wl_int32 repo_add_dns(wl_char* host, wl_char* ip);
wl_int32 repo_get_dns(wl_char* host, repo_dns* dns);

// wl_bool  repo_is_speech_msg_full(void);
// wl_int32 repo_add_speech_msg(wl_msg* msg);
// wl_int32 repo_get_next_speech_msg(wl_char* msgkey, wl_msg* msg);
// wl_int32 repo_delete_speech_msg(wl_char* msgkey);
// wl_bool  repo_is_ptt_msg_full(void);
// wl_int32 repo_add_ptt_msg(wl_msg* msg);
// wl_int32 repo_get_ptt_msg(wl_char* msgkey, wl_msg* msg);
// wl_int32 repo_get_next_ptt_msg(wl_char* msgkey, wl_msg* msg);
// wl_int32 repo_delete_ptt_msg(wl_char* msgkey);
// wl_int32 repo_add_playback_msg(wl_msg* msg);
// wl_int32 repo_get_next_playback_msg(wl_char* msgkey, wl_msg* msg);
wl_int32 repo_set_attach_group_session(wl_uint64 sessionid);
wl_bool  repo_is_attach_group_session(wl_uint64 sessionid);

wl_int32 repo_add_burst_playback(repo_playback* playback);
/**
 * @description: 获取回放数据
 * @param idx 回放索引
 * @return 回放数据 需要使用者是否内存
 */
repo_playback* repo_get_burst_playback(wl_uint32 idx);

void     repo_set_tts_audio(wl_char* text, wl_uint32 textlen, wl_char* audio, wl_uint32 audiolen);
wl_int32 repo_get_tts_audio(wl_char* text, wl_uint32 textlen, wl_char** audio, wl_uint32* audiolen);

#ifdef __cplusplus
}
#endif
#endif
